import Konva from "konva";
import { SLIDE_PADDING } from "../Config";

type IRange = { x: number; y: number; width: number; height: number };

/**
 * 传入 container 确定最终的 容器
 */
export function getContainer(container: Element | HTMLElement | string) {
  if (typeof container === "string") {
    const dom = document.querySelector(container);
    if (!dom) throw new Error(`container ${container} not found`);
    return dom;
  }
  return container;
}

/**
 * 解析 konva 容器宽高 16：9
 * @param { HTMLDivElement } container 容器
 * @param { number } w  自定义宽
 * @param { number } h  自定义高
 */
export function getKonvaBoxSize(
  container: HTMLDivElement,
  w?: number,
  h?: number
) {
  // 如果用户传递了宽高，则使用用户自定义的宽高，并且需要同步修正 宽高比（包括导出时）
  if (w && h) return { width: w, height: h };

  // 不然依照屏幕尺寸 16/9 进行解析
  const slideRatio = 16 / 9;

  // 有偏移量
  const clientWidth = container.clientWidth - SLIDE_PADDING;
  const clientHeight = container.clientHeight - SLIDE_PADDING;

  //  要以最长边为准
  const ratioState = clientWidth / clientHeight > slideRatio;
  const width = ratioState ? clientHeight * slideRatio : clientWidth;
  const height = ratioState ? clientHeight : clientWidth / slideRatio;
  return { width, height };
}

/**
 * 需要进行 innerHtml 文本替换
 *  注意：简单版哈，大家根据需求自行完善相关方法
 */
export function replaceInnerHtml(text: string) {
  return text.replace(/</g, "").replace(/>/g, "").replace(/br/g, "\n");
}

/**
 * 解析图片类型: File | string | Bolb
 * 目前不支持在线URL，后续使用服务器，可考虑使用 fetch 请求图片转 Blob
 */
export async function getImageSource(source: string | File | Blob) {
  return new Promise<string>((resolve) => {
    if (source instanceof File || source instanceof Blob) {
      // File Blob 相同的处理 创建文件读取器
      const fileReader = new FileReader();
      fileReader.readAsDataURL(source);
      fileReader.onload = () => {
        const value = <string>fileReader.result;
        resolve(value);
      };
    } else resolve(source);
  });
}

/**
 * 判断节点是否在范围内
 * @param node 传入需要判断的Konva节点
 * @param range 传入范围 {x,y,width,height}
 */
export function haveInterSection(node: Konva.Node, range: IRange) {
  const { x, y, width, height } = node.attrs;
  return Konva.Util.haveIntersection({ x, y, width, height }, range);
}

/**
 * 将 konva fill stroke 等颜色属性 转成 input value 类型 input 不支持 #ddd ，支持 #dddddd
 *  颜色相关工具函数 color_getHexColor
 *  颜色相关工具函数 color_hexToRGB
 *  颜色相关工具函数 color_hexToHsl
 *  颜色相关工具函数 color_rgbToHex
 *  颜色相关工具函数 color_hslToHex
 */
export function color_getHexColor(color: string) {
  if (!color) return "transparent";
  // 这里要判断支持 rgb hex
  const { r = 0, g = 0, b = 0 } = Konva.Util.colorToRGBA(color) || {};
  return "#" + Konva.Util._rgbToHex(r, g, b);
}
export function color_hexToRGB(color: string) {
  return Konva.Util.colorToRGBA(color) || { r: 0, g: 0, b: 0 };
}
export function color_hexToHsl(color: string) {
  let { r = 0, g = 0, b = 0 } = Konva.Util.colorToRGBA(color) || {};
  r /= 255;
  g /= 255;
  b /= 255;

  const max = Math.max(r, g, b),
    min = Math.min(r, g, b);
  let h,
    s,
    l = (max + min) / 2;

  if (max === min) {
    h = s = 0; //  achromatic
  } else {
    const d = max - min;
    s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
    s = s * 100;

    if (max === r && g >= b) {
      h = (60 * (g - b)) / d + 0;
    } else if (max === r && g < b) {
      h = (60 * (g - b)) / d + 360;
    } else if (max === g) {
      h = (60 * (b - r)) / d + 120;
    } else if (max === b) {
      h = (60 * (r - g)) / d + 240;
    }
    h = h! + 0;
  }

  h = h + 0;
  l = l * 100;
  s = s ? s : 0; // don't show error for s if undefined

  return {
    h: h,
    s: s,
    l: l,
  };
}
export function color_rgbToHex(r: number, g: number, b: number) {
  return "#" + Konva.Util._rgbToHex(r, g, b);
}
export function color_hslToHex(h: number, s: number, l: number) {
  // 转成 RGB colorToRGBA
  const hsl = `hsl(${parseInt(h.toString())}, ${s}%, ${l}%)`;
  const { r = 0, g = 0, b = 0 } = Konva.Util.colorToRGBA(hsl) || {};
  return "#" + Konva.Util._rgbToHex(r, g, b);
}
